unit uFormMain;

{$mode objfpc}{$H+}

interface

uses
    types,
    Classes, SysUtils, simpleipc, Forms, Controls, Graphics,
    Dialogs, ExtCtrls, Buttons, StdCtrls, Menus, ActnList,
    LMessages, sqldb,
    uTypes, uInterfaces, uCore, uMessages,
    uFrameManager, uContentBlocker,

    uFrameClassifTV,

    uFormBrwBase, uFormBrwChromium, uFormAbout;

type

    { TFrmMain }

    TFrmMain = class(TForm, IISCore)
        aclMain: TActionList;
        actCBReload: TAction;
        actNewPage: TAction;
        ApplicationProperties1: TApplicationProperties;
        btnPanelDownloads: TSpeedButton;
        imgWinMove: TImage;
        lblPanelHeader: TLabel;
        MenuItem1: TMenuItem;
        MenuItem2: TMenuItem;
        MenuItem3: TMenuItem;
        MenuItem4: TMenuItem;
        MenuItem5: TMenuItem;
        MenuItem6: TMenuItem;
        MenuItem7: TMenuItem;
        MenuItem8: TMenuItem;
        mniExit: TMenuItem;
        Panel1: TPanel;
        pnlNotifications: TPanel;
        pnlQBA: TPanel;
        pnlWinMove: TPanel;
        pnlClient: TPanel;
        pnlWindowButtons: TPanel;
        pnlToolbarSpacer01: TPanel;
        pnlPanelHeader: TPanel;
        pnlTabs: TPanel;
        pnlMain: TPanel;
        pnlPanels: TPanel;
        pnlTopToolbar: TPanel;
        pnlSideToolbar: TPanel;
        btnOrcis: TSpeedButton;
        btnNewPage: TSpeedButton;
        btnTrash: TSpeedButton;
        btnFavorites: TSpeedButton;
        btnPanelBookmark: TSpeedButton;
        btnPanelMail: TSpeedButton;
        btnPanelRSS: TSpeedButton;
        mnuMain: TPopupMenu;
        IPCServer: TSimpleIPCServer;
        btnPanelHistory: TSpeedButton;
        btnWinClose: TSpeedButton;
        btnWinMaximize: TSpeedButton;
        btnWinMinimize: TSpeedButton;
        btnPanelShowHide: TSpeedButton;
        btnQBShowHide: TSpeedButton;
        splMain: TSplitter;
        procedure actCBReloadExecute(Sender: TObject);
        procedure actNewPageExecute(Sender: TObject);
        procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean
            );
        procedure btnOrcisClick(Sender: TObject);
        procedure BrwButtonClick(Sender: TObject);
        procedure BrwButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
            X, Y: integer);
        procedure BrwButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
            X, Y: integer);
        procedure btnQBShowHideClick(Sender: TObject);
        procedure btnTrashClick(Sender: TObject);
        procedure FormActivate(Sender: TObject);
        procedure FormDeactivate(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure FormWindowStateChange(Sender: TObject);
        procedure imgWinMoveMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
        procedure imgWinMoveMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
        procedure imgWinMoveMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
        procedure btnWinCloseClick(Sender: TObject);
        procedure btnWinMaximizeClick(Sender: TObject);
        procedure btnWinMinimizeClick(Sender: TObject);
        procedure IPCServerMessage(Sender: TObject);
        procedure MenuItem4Click(Sender: TObject);
        procedure mniExitClick(Sender: TObject);
        procedure pnlClientMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
            X, Y: integer);
        procedure pnlClientMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
        procedure pnlClientMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
            X, Y: integer);
        procedure pnlPanelsClick(Sender: TObject);
        procedure pnlTabsDblClick(Sender: TObject);
        procedure pnlTabsResize(Sender: TObject);
        procedure btnPanelShowHideClick(Sender: TObject);
    private
        FFrames: TFrameManager;
        FMouseButton: TMouseButton;
        FNDFormState: TWindowState;
        FNDPanelsVisible: boolean;
        FormMovePoint: TPoint;
        FormMoving: boolean;

        FRestoreRect: TRect;

        procedure SaveRestoreRect;
        procedure Maximize;
        procedure Restore;
        procedure SetNDPanelsVisible(AValue: boolean);
        procedure SwitchNDFormState;
        function GetSizeSide(const ARect: TRect; const AWidth: integer; const APoint: TPoint): TSizeSide;

        procedure SetNDFormState(AValue: TWindowState);

        procedure ShowPanel(const APanel: string);

        procedure SetWindowHeader;

        procedure AdjustPageButtons;
    protected
        procedure Init;
        procedure Done;
        procedure InitImages;
        {.$ifdef windows}
        procedure LMNCHitTest(var AMsg: TLMNCHITTEST); message LM_NCHITTEST;
        {.$endif}
        procedure NewWebPage(
                const AURL: string;
                const AEngine: TRenderEngine;
                const AActivate: Boolean);
        procedure TryClose;

        // Dummy IISCore methods
        procedure RegisterModule(AModule: IISModule);
        function GetDBConnection: TSQLConnection;
        function ModuleByCode(const ACode: string): IISModule;
    public
        constructor Create(TheOwner: TComponent); override;

        property NDFormState: TWindowState read FNDFormState write SetNDFormState;
        property NDPanelsVisible: boolean read FNDPanelsVisible write SetNDPanelsVisible;
    end;

var
    FrmMain: TFrmMain;

const
    IPCServerID = 'F9DAD081-9EAF-4B55-BB12-D44E8458BA28';

implementation

const
    { WM_NCHITTEST message  }
    HTBOTTOM = 15;
    HTBOTTOMLEFT = 16;
    HTBOTTOMRIGHT = 17;
    HTCAPTION = 2;
    HTCLIENT = 1;
    HTERROR = -(2);
    HTGROWBOX = 4;
    HTHSCROLL = 6;
    HTLEFT = 10;
    HTMENU = 5;
    HTNOWHERE = 0;
    HTREDUCE = 8;
    HTRIGHT = 11;
    HTSIZE = 4;
    HTSYSMENU = 3;
    HTTOP = 12;
    HTTOPLEFT = 13;
    HTTOPRIGHT = 14;
    HTTRANSPARENT = -(1);
    HTVSCROLL = 7;
    HTZOOM = 9;

    HTBORDER = 18;
    HTSIZEFIRST = HTLEFT;
    HTSIZELAST = HTBOTTOMRIGHT;
    HTOBJECT = 19;
    HTCLOSE = 20;
    HTHELP = 21;
    HTMINBUTTON = HTREDUCE;
    HTMAXBUTTON = HTZOOM;

{$R *.lfm}

{ TFrmMain }

procedure TFrmMain.btnOrcisClick(Sender: TObject);
var
    p: TPoint;
begin
    p := Point(btnOrcis.Left, btnOrcis.Top + btnOrcis.Height);
    p := pnlTopToolbar.ClientToScreen(p);
    mnuMain.PopUp(p.x, p.y);
end;

procedure TFrmMain.BrwButtonClick(Sender: TObject);
var
    b: TSpeedButton;
    i: integer;
begin
    b := Sender as TSpeedButton;
    i := FFrames.IndexByButton(b);
    if i > -1 then
    begin
        case FMouseButton of
            mbLeft:
                FFrames.ActiveFrameIndex := i;
            mbRight:
                ;
            mbMiddle:
                ShowMessage('foo');
        end;
    end;
end;

procedure TFrmMain.BrwButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
    FMouseButton := Button;
end;

procedure TFrmMain.BrwButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
var
    i: integer;
    b: TSpeedButton;
begin
    b := Sender as TSpeedButton;
    if Button = mbMiddle then
    begin
        i := FFrames.IndexByButton(b);
        if i = FFrames.ActiveFrameIndex then
        begin
            // if closing active frame - show previouse frame
            if FFrames.PrevFrameIndex > -1 then
                FFrames.ShowFrame(FFrames.PrevFrameIndex);
        end;

        if i > -1 then
        begin
            FFrames.Delete(i);
        end;
        //if i > 0 then
        //    FFrames.ShowFrame(i-1);
        { TODO 2 -oND -cUI internals : Free button via message }
        b.Free;
        AdjustPageButtons;
    end;
end;

procedure TFrmMain.btnQBShowHideClick(Sender: TObject);
begin
    pnlQBA.Visible := not pnlQBA.Visible;
end;

procedure TFrmMain.btnTrashClick(Sender: TObject);
begin
end;

procedure TFrmMain.FormActivate(Sender: TObject);
begin
    Self.Color := clMoneyGreen;

    pnlTopToolbar.Color := clActiveBorder;
    pnlSideToolbar.Color := clActiveBorder;
    pnlWinMove.Color := clActiveBorder;

    btnWinClose.Transparent := False;
    btnWinMaximize.Transparent := False;
    btnWinMinimize.Transparent := False;
end;

procedure TFrmMain.FormDeactivate(Sender: TObject);
begin
    Self.Color := clMoneyGreen;

    pnlTopToolbar.Color := clInactiveBorder;
    pnlSideToolbar.Color := clInactiveBorder;
    pnlWinMove.Color := clInactiveBorder;

    btnWinClose.Transparent := True;
    btnWinMaximize.Transparent := True;
    btnWinMinimize.Transparent := True;
end;

procedure TFrmMain.FormShow(Sender: TObject);
begin
    actNewPage.Execute;

    ISCore.SplashClose;
end;

procedure TFrmMain.FormWindowStateChange(Sender: TObject);
begin
    //SetWindowHeader;
end;

procedure TFrmMain.imgWinMoveMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
    FormMoving := True;
    FormMovePoint.x := X;
    FormMovePoint.y := Y;
    SetCaptureControl(imgWinMove);
end;

procedure TFrmMain.imgWinMoveMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
var
    p: TPoint;
begin
    if FormMoving then
    begin
        p.x := X - FormMovePoint.x;
        p.y := Y - FormMovePoint.y;
        Self.Left := Self.Left + p.x;
        Self.Top := Self.Top + p.y;
    end;
end;

procedure TFrmMain.imgWinMoveMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
    FormMoving := False;
    SetCaptureControl(nil);
end;

procedure TFrmMain.btnWinCloseClick(Sender: TObject);
begin
    TryClose;
end;

procedure TFrmMain.btnWinMaximizeClick(Sender: TObject);
begin
    SwitchNDFormState;
end;

procedure TFrmMain.btnWinMinimizeClick(Sender: TObject);
begin
    Application.Minimize;
end;

procedure TFrmMain.IPCServerMessage(Sender: TObject);
begin
    if IPCServer.StringMessage <> '' then
    begin

    end;
end;

procedure TFrmMain.MenuItem4Click(Sender: TObject);
begin
    DoAbout;
end;

procedure TFrmMain.mniExitClick(Sender: TObject);
begin
    TryClose;
end;

procedure TFrmMain.pnlClientMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
    SetCaptureControl(pnlClient);
    FormMovePoint := Point(X, Y);
    FormMoving := True;
end;

procedure TFrmMain.pnlClientMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
var
    r: TRect;
    ss: TSizeSide;
    cur: TCursor;
begin
    ss := GetSizeSide(pnlClient.BoundsRect, 10, Point(X, Y));
    r := Self.BoundsRect;
    case ss of
        ssNone:
        begin
            cur := crDefault;
        end;
        ssLeftTop:
        begin
            cur := crSizeNWSE;
        end;
        ssLeftBottom:
        begin
            cur := crSizeNESW;
        end;
        ssRightTop:
        begin
            cur := crSizeNESW;
        end;
        ssRightBottom:
        begin
            cur := crSizeNWSE;
        end;
        ssLeft:
        begin
            cur := crSizeWE;
        end;
        ssRight:
        begin
            cur := crSizeWE;
        end;
        ssTop:
        begin
            cur := crSizeNS;
        end;
        ssBottom:
        begin
            cur := crSizeNS;
        end;
    end;
    if FormMoving then
        Self.BoundsRect := r;

    pnlClient.Cursor := cur;
end;

procedure TFrmMain.pnlClientMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
    SetCaptureControl(nil);
    FormMoving := False;
end;

procedure TFrmMain.pnlPanelsClick(Sender: TObject);
begin

end;

procedure TFrmMain.pnlTabsDblClick(Sender: TObject);
begin
    SwitchNDFormState;
end;

procedure TFrmMain.pnlTabsResize(Sender: TObject);
begin
    AdjustPageButtons;
end;

procedure TFrmMain.btnPanelShowHideClick(Sender: TObject);
begin
    NDPanelsVisible := not NDPanelsVisible;
end;

procedure TFrmMain.SaveRestoreRect;
begin
    FRestoreRect := Self.BoundsRect;
end;

procedure TFrmMain.Maximize;
var
    p: TPoint;
    m: TMonitor;
begin
    SaveRestoreRect;
    p.x := Self.Left;
    p.y := Self.Top;
    m := Screen.MonitorFromPoint(p);
    if not Assigned(m) then
        m := Screen.Monitors[0];
    Self.BoundsRect := m.WorkareaRect;
    pnlWindowButtons.Width :=
        btnWinMinimize.Width + btnWinMaximize.Width + btnWinClose.Width;
    pnlClient.BorderSpacing.Around := 0;
    FNDFormState := wsMaximized;
end;

procedure TFrmMain.Restore;
begin
    Self.BoundsRect := FRestoreRect;
    pnlWindowButtons.Width :=
        btnWinMinimize.Width + btnWinMaximize.Width + btnWinClose.Width + 48;
    pnlClient.BorderSpacing.Around := 8;
    FNDFormState := wsNormal;
end;

procedure TFrmMain.SetNDPanelsVisible(AValue: boolean);
begin
    if FNDPanelsVisible = AValue then
        Exit;
    FNDPanelsVisible := AValue;
    pnlPanels.Visible := AValue;
    splMain.Visible := AValue;
end;

procedure TFrmMain.SwitchNDFormState;
begin
    if FNDFormState = wsMaximized then
    begin
        NDFormState := wsNormal;
        Exit;
    end;
    if FNDFormState = wsNormal then
    begin
        NDFormState := wsMaximized;
        Exit;
    end;
end;

function TFrmMain.GetSizeSide(const ARect: TRect; const AWidth: integer; const APoint: TPoint): TSizeSide;
var
    rt, rb, rl, rr: TRect;
    s: TSize;
    p: TPoint;
begin
    p := APoint;
    // Get size areas
    // -----------------------------------------------------
    s := Size(ARect);
    rt := Rect(0, 0, s.cx, AWidth);
    rb := Rect(0, s.cy - AWidth, s.cx, s.cy);
    rl := Rect(0, 0, AWidth, s.cy);
    rr := Rect(s.cx - AWidth, 0, s.cx, s.cy);

    // Left-Top
    if PtInRect(rl, p) and PtInRect(rt, p) then
    begin
        Result := ssLeftTop;
        Exit;
    end;
    // Left-Bottom
    // -----------------------------------------------------
    if PtInRect(rl, p) and PtInRect(rb, p) then
    begin
        Result := ssLeftBottom;
        Exit;
    end;
    // Right-Top
    // -----------------------------------------------------
    if PtInRect(rr, p) and PtInRect(rt, p) then
    begin
        Result := ssRightTop;
        Exit;
    end;
    // Right-Bottom
    // -----------------------------------------------------
    if PtInRect(rr, p) and PtInRect(rb, p) then
    begin
        Result := ssRightBottom;
        Exit;
    end;
    // Left
    // -----------------------------------------------------
    if PtInRect(rl, p) then
    begin
        Result := ssLeft;
        Exit;
    end;
    // Right
    // -----------------------------------------------------
    if PtInRect(rr, p) then
    begin
        Result := ssRight;
        Exit;
    end;
    // Top
    // -----------------------------------------------------
    if PtInRect(rt, p) then
    begin
        Result := ssTop;
        Exit;
    end;
    // Bottom
    // -----------------------------------------------------
    if PtInRect(rb, p) then
    begin
        Result := ssBottom;
        Exit;
    end;
    Result := ssNone;
end;

procedure TFrmMain.SetNDFormState(AValue: TWindowState);
begin
    if FNDFormState = AValue then
        Exit;
    FNDFormState := AValue;
    if FNDFormState = wsMaximized then
    begin
        Maximize;
        Exit;
    end;
    if FNDFormState = wsNormal then
    begin
        Restore;
        Exit;
    end;
end;

procedure TFrmMain.ShowPanel(const APanel: string);
begin
    // Get panel interface
    // -----------------------------------------------------

    // Place panel on the panel's container
    // -----------------------------------------------------

    // Create/Find and activate frame
    // -----------------------------------------------------

    // Unselect web-page buttons, select panel's button
    // -----------------------------------------------------


    case LowerCase(APanel) of
        'bookmarks':
        begin

        end;
    end;
end;

procedure TFrmMain.SetWindowHeader;
begin
    if WindowState in [wsMaximized, wsFullScreen] then
    begin
        pnlWindowButtons.Visible := True;
        BorderStyle := bsNone;
    end
    else
    begin
        pnlWindowButtons.Visible := False;
        BorderStyle := bsSizeable;
    end;
end;

procedure TFrmMain.AdjustPageButtons;
const
    CMaxButtonWidth: Integer = 512;
    CMinButtonWidth: Integer = 24;
var
    w, bw: Integer;
    i, c: Integer;
begin
    w := pnlTabs.Width;
    c := FFrames.Count;
    if c > 0 then
    begin
        bw := w div c;
        if bw < CMinButtonWidth then
            bw := CMinButtonWidth
        else
            if (CMaxButtonWidth <> 0) and (bw > CMaxButtonWidth) then
                bw := CMaxButtonWidth;
        for i := 0 to c - 1 do
        begin
            FFrames[i].Button.Width := bw;
        end;
    end;
end;

procedure TFrmMain.Init;
var
    r, dr: TRect;
begin
    ISCore.SplashSetState('Main form:');

    InitImages;

    NDFormState := wsNormal;
    NDPanelsVisible := True;

    pnlPanels.Width := 256;
    pnlQBA.Visible := False;

    // Check is form in the visible part of the screen
    r := Self.BoundsRect;
    dr := Screen.DesktopRect;

    if not dr.Contains(r.TopLeft) then
    begin
        r.MoveToLT(dr.Left, dr.Top);
        Self.BoundsRect := r;
    end;

    Maximize;

    with TFraClassifTV.Create(Application) as IISPanel do
    begin
        EmbedInto(pnlPanels);
        lblPanelHeader.Caption := GetCaption;
    end;

    ISCore.SplashUpdateState(100);

    //ISCore.SplashClose;
end;

procedure TFrmMain.Done;
begin
end;

procedure TFrmMain.InitImages;
begin
    aclMain.Images := ISCore.Pic16;
    mnuMain.Images := ISCore.Pic16;

    ISCore.SetActGlyph('plus_button', actNewPage);

    // For now cotrols glyphs are not changed when action's image index changed
    // So we have to change glyphs manually
    ISCore.SetBtnGlyph('plus_button', btnNewPage);

    // Panels
    ISCore.SetBtnGlyph('toolbar_bookmark', btnQBShowHide);
    ISCore.SetBtnGlyph('application_side_tree', btnPanelShowHide);
    ISCore.SetBtnGlyph('star', btnPanelBookmark);
    ISCore.SetBtnGlyph('clock_history_frame', btnPanelHistory);
    ISCore.SetBtnGlyph('download', btnPanelDownloads);
    ISCore.SetBtnGlyph('rss', btnPanelRSS);
    ISCore.SetBtnGlyph('email', btnPanelMail);

    // Toolbar
    ISCore.SetBtnGlyph('plus_button', btnNewPage);
    ISCore.SetBtnGlyph('asterisk_orange', btnFavorites);
    ISCore.SetBtnGlyph('recycle', btnTrash);

    // Window
    ISCore.SetToImage('transform_move', imgWinMove);
    ISCore.SetBtnGlyph('application_put', btnWinMinimize);
    ISCore.SetBtnGlyph('arrow_inout', btnWinMaximize);
    ISCore.SetBtnGlyph('door_in', btnWinClose);


    //ISCore.SetBtnGlyph('', );
    //ISCore.SetBtnGlyph('', );
end;

procedure TFrmMain.LMNCHitTest(var AMsg: TLMNCHITTEST);
begin
    case GetSizeSide(Self.BoundsRect, 16, Self.ScreenToClient(Point(AMsg.XPos, AMsg.YPos))) of
        ssNone:
        begin
            AMsg.Result := HTNOWHERE;
        end;
        ssLeftTop:
        begin
            AMsg.Result := HTTOPLEFT;
        end;
        ssLeftBottom:
        begin
            AMsg.Result := HTBOTTOMLEFT;
        end;
        ssRightTop:
        begin
            AMsg.Result := HTTOPRIGHT;
        end;
        ssRightBottom:
        begin
            AMsg.Result := HTBOTTOMRIGHT;
        end;
        ssLeft:
        begin
            AMsg.Result := HTLEFT;
        end;
        ssRight:
        begin
            AMsg.Result := HTRIGHT;
        end;
        ssTop:
        begin
            AMsg.Result := HTTOP;
        end;
        ssBottom:
        begin
            AMsg.Result := HTBOTTOM;
        end;
    end;
    //if AMsg.Result = HTCLIENT then AMsg.Result := HTLEFT;
end;

procedure TFrmMain.actNewPageExecute(Sender: TObject);
begin
    NewWebPage('', reCEF, True);
end;

procedure TFrmMain.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
begin
    // Handle internal message queue
end;

procedure TFrmMain.actCBReloadExecute(Sender: TObject);
begin
    ReloadContentBlocker;
end;

constructor TFrmMain.Create(TheOwner: TComponent);
begin
    inherited Create(TheOwner);
    { TODO 1 -oND -cGeneral : Check "unique instance" option }
    { TODO 1 -oND -cGeneral : Check for another instance }
    IPCServer.ServerID := IPCServerID;
    IPCServer.StartServer;

    FMouseButton := mbExtra2;
    FFrames := TFrameManager.Create(pnlMain);

    BorderStyle := bsNone;

    Init;
end;

procedure TFrmMain.NewWebPage(
        const AURL: string;
        const AEngine: TRenderEngine;
        const AActivate: Boolean);
    procedure InitButton(ABtn: TSpeedButton);
    begin
        ABtn.Flat := True;
        ABtn.Margin := 4;
        ABtn.Caption := 'Blank';
        //ABtn.Spacing := 4;
        ABtn.BorderSpacing.Left := 1;
        ABtn.BorderSpacing.Right := 1;
        ABtn.BorderSpacing.Bottom := 1;
        ABtn.Parent := pnlTabs;
        ABtn.Width := 256;
        ABtn.Left := pnlTabs.Width;
        ABtn.Align := alLeft;
        ABtn.OnMouseDown := @BrwButtonMouseDown;
        ABtn.OnMouseUp := @BrwButtonMouseUp;
        ABtn.OnClick := @BrwButtonClick;
        ABtn.GroupIndex := 1;
        ABtn.AllowAllUp := False;
        ABtn.Down := AActivate;
        ABtn.Font.Size := 7;
        ABtn.Transparent := False;
    end;

    //function CreateButton: TControl;
    //var
    //    b: TBCButton;
    //begin
    //    b := TBCButton.Create(Self);
    //    //b.StateNormal.Assign();
    //    b.Assign(BCButton1);
    //    b.Visible := True;
    //
    //    Exit(b);
    //end;

var
    f: TFrameContainer;
    b: TSpeedButton;
begin
    f := FFrames.Add(TFrmBrwChromium.Create(Application), 'foo');
    //FMsgTargets.AddTarget(f.Frame as TFrmBrwBase).MTID := IntToStr(IntPtr(@f.Frame));
    //f := FFrames.Add(TBrwContainer);
    f.OwnButton := True;
    (f.Frame as TFrmBrwBase).FocusAddressField;
    if AActivate then
        FFrames.ShowFrame(FFrames.Count - 1);
    if AURL <> '' then
    begin
        (f.Frame as TFrmBrwBase).PostTextMessage(f.Frame.Handle, ISM_TMP_TEXT, ISM_TMP_BRW_LOAD_URL, AURL);
        //LoadURL(AURL);
    end;
    b := f.CreateButton(TSpeedButton) as TSpeedButton;
    //f.OnTitleChange := (f.Frame as TFrmBrwBase).OnTitleChange;
    (f.Frame as TFrmBrwBase).OnTitleChange := @f.EventTitleChange;
    InitButton(b);
    AdjustPageButtons;
end;

procedure TFrmMain.TryClose;
begin
    // Check for ...

    // Destroy all existing frames
    while FFrames.Count > 0 do
    begin
        FFrames.Delete(0);
        //Sleep(500);
        Application.ProcessMessages;
    end;

    //Sleep(500);

    // Flush queued messegas
    Application.ProcessMessages;

    Close;

    //Sleep(500);
end;

procedure TFrmMain.RegisterModule(AModule: IISModule);
begin
end;

function TFrmMain.GetDBConnection: TSQLConnection;
begin

end;

function TFrmMain.ModuleByCode(const ACode: string): IISModule;
begin

end;

end.


